package com.yuke.cloud.service.smc.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yuke.cloud.common.base.constant.MQConstants;
import com.yuke.cloud.common.base.enums.ErrorCodeEnum;
import com.yuke.cloud.common.core.mq.RabbitMetaMessage;
import com.yuke.cloud.common.core.mq.RabbitSender;
import com.yuke.cloud.common.util.wrapper.WrapMapper;
import com.yuke.cloud.common.util.wrapper.Wrapper;
import com.yuke.cloud.service.api.omc.dto.GoodsInfo;
import com.yuke.cloud.service.api.omc.exceptions.OmcBizException;
import com.yuke.cloud.service.api.omc.service.OmcOrderFeignApi;
import com.yuke.cloud.service.api.pmc.dto.ProdCategoryDto;
import com.yuke.cloud.service.api.pmc.exceptions.PmcBizException;
import com.yuke.cloud.service.api.pmc.service.PmcFeignApi;
import com.yuke.cloud.service.api.smc.dto.GoodsAndSpecInfoDto;
import com.yuke.cloud.service.api.smc.dto.ShopGoodsSalePriceDto;
import com.yuke.cloud.service.api.wmc.service.WmcStorageFeignApi;
import com.yuke.cloud.service.smc.dao.ShopGoodsMapper;
import com.yuke.cloud.service.api.pmc.dto.ProdSpecInfoDto;
import com.yuke.cloud.service.smc.dto.*;
import com.yuke.cloud.service.smc.entity.ShopGoods;
import com.yuke.cloud.service.smc.service.ShopGoodsService;
import com.yuke.cloud.common.core.support.BaseService;
import com.yuke.cloud.service.smc.service.ShopService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;


/**
 * Created by wg on 2018/09/10.
 */
@Import(RabbitSender.class)
@Slf4j
@Service
@Transactional
public class ShopGoodsServiceImpl extends BaseService<ShopGoods> implements ShopGoodsService {
    @Resource
    private ShopGoodsMapper shopGoodsMapper;
    @Resource
    private ShopService shopService;
    @Resource
    private PmcFeignApi pmcFeignApi;
    @Resource
    private OmcOrderFeignApi omcOrderFeignApi;
    @Autowired
    private RabbitSender rabbitSender;

    @Value("${yuke.shop.deliver_distance}")
    private Integer deliverDistance;

    @Resource
    WmcStorageFeignApi wmcStorageFeignApi;

    @Override
    public void applyGoods(Long shopId, Long specId) {
        Example example = new Example(ShopGoods.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("shopId", shopId);
        criteria.andEqualTo("productId", specId);
        // mod by wg 20190320 如果商品申请没通过商家可以重新申请
        List<ShopGoods> shopGoodsList = shopGoodsMapper.selectByExample(example);
        if (shopGoodsList != null && shopGoodsList.size() == 1 && (shopGoodsList.get(0).getGoodsStatus() == 3 || shopGoodsList.get(0).getGoodsStatus() == 4)) {
            shopGoodsList.get(0).setGoodsStatus((byte)1);
            this.update(shopGoodsList.get(0));
            this.shopGoodsReviewMessage(shopGoodsList.get(0).getShopGoodsId());
            return;
        }else if (shopGoodsList != null && shopGoodsList.size() > 0) {
            log.warn("--- applyGoods(shopId, specId)：该商品已存在，不需要再次申请，参数：{}, {} ---", shopId, specId);
            return;
        }

//        if (shopGoodsMapper.selectCountByExample(example) > 0) {
//            log.warn("--- applyGoods(shopId, specId)：该商品已存在，不需要再次申请，参数：{}, {} ---", shopId, specId);
//            return;
//        }

        JSONObject prices = pmcFeignApi.getPriceBySpecId(specId);
        if (prices == null || prices.equals("")) {
            log.error("--- pmcFeignApi.getPriceBySpecId(specId)内部异常，参数：{} ---", specId);
            throw new PmcBizException(ErrorCodeEnum.GL99990002);
        }
        Map<String, Integer> pricesMap = JSONObject.toJavaObject(prices, Map.class);
        ShopGoods shopGoods = new ShopGoods();
        shopGoods.setShopId(shopId);
        shopGoods.setProductId(specId);
        shopGoods.setGoodsStatus((byte)1);
        shopGoods.setIsAlive(false);
        shopGoods.setSupplyPrice(pricesMap.get("stock_price"));
        shopGoods.setSalePrice(pricesMap.get("guidance_price"));
        shopGoods.setStockCount(0);
        int count = this.save(shopGoods);
        if (count > 0)
            this.shopGoodsReviewMessage(shopGoods.getShopGoodsId());
    }

    private void shopGoodsReviewMessage(Long shopGoodsId) {
        log.info("--- Enter shopGoodsReviewMessage(Long shopGoodsId)，参数：{} ---", shopGoodsId);
        Map map = new HashMap();
        map.put("MessageType", "shopGoodsReview");
        map.put("body", "通知店铺管理员，有商品申请需要审核");
        RabbitMetaMessage rabbitMetaMessage = new RabbitMetaMessage();
        rabbitMetaMessage.setExchange(MQConstants.BUSINESS_EXCHANGE);
        rabbitMetaMessage.setRoutingKey(MQConstants.BUSINESS_KEY_TMC);
        rabbitMetaMessage.setPayload(JSON.toJSONString(map));
        try {
            rabbitSender.send(rabbitMetaMessage);
        } catch (Exception e) {
            e.printStackTrace();
        }
        log.info("--- Leave shopGoodsReviewMessage(Long shopGoodsId) ---");
    }

    @Override
    public void updateGoodsPrice(Long shopGoodId,Integer salePrice){
        shopGoodsMapper.updateGoodsPrice(shopGoodId,salePrice);
    }

    @Override
    public void goodsIsAlive(String shopGoodsIds, Integer isAlive) {
        List<Long> shopGoodsList = Arrays.asList(shopGoodsIds.split(",")).stream().map(s -> Long.valueOf(s)).collect(Collectors.toList());
        shopGoodsMapper.goodsIsAlive(shopGoodsList, isAlive);
    }

    @Override
    public List<ShopGoods> getListByCondition(ShopGoods goods) {
        List<ShopGoods> shopGoods = new ArrayList<>();
        List<ShopGoods> shopGoodsList = shopGoodsMapper.getListByCondition(goods);
        if (shopGoodsList.size() == 0) {
            return shopGoodsList;
        }
        ProdSpecInfoDto prodSpecInfoDto = new ProdSpecInfoDto();
        if (goods.getSpecName() != null && goods.getSpecName() != ""){
            prodSpecInfoDto.setSpecName(goods.getSpecName());
        }
        List<ProdSpecInfoDto> prodSpecInfoDtos = pmcFeignApi.getSpecBySpecName(prodSpecInfoDto);
        if (prodSpecInfoDtos == null || prodSpecInfoDtos.size() == 0) {
            log.error("--- pmcFeignApi.getSpecBySpecName(prodSpecInfoDto)内部异常，参数：{} ---", prodSpecInfoDto);
            throw new PmcBizException(ErrorCodeEnum.GL99990002);
        }
        for (ShopGoods shopGood : shopGoodsList) {
            Optional<ProdSpecInfoDto> specInfoDto = prodSpecInfoDtos.stream().filter(spec -> spec.getSpecId().equals(shopGood.getProductId())).findFirst();
            if (specInfoDto.isPresent()) {
                shopGood.setSpecName(specInfoDto.get().getSpecName());
                shopGoods.add(shopGood);
            }
        }
        return shopGoods;
    }

    /**
     * 获得店铺商品的月销量
     * @param goodsDtos
     * @return
     */
    private List<GoodsInfo> getCount(List<GoodsDto> goodsDtos) {
        List<GoodsInfo> goodsInfoList = new ArrayList<>();
        for (GoodsDto goodsDto : goodsDtos) {
            GoodsInfo goodsInfo = new GoodsInfo();
            goodsInfo.setShopGoodsId(goodsDto.getShopGoodsId());
            goodsInfo.setShopId(goodsDto.getShopId());
            goodsInfo.setProductId(goodsDto.getProductId());
            goodsInfoList.add(goodsInfo);
        }
        List<GoodsInfo> goodsInfos = omcOrderFeignApi.countmonthnumbyprimikey(goodsInfoList);
        if (goodsInfos == null || goodsInfos.size() == 0) {
            log.error("--- omcOrderFeignApi.countmonthnumbyprimikey(goodsInfoList)内部异常，参数：{} ---", goodsInfoList);
            throw new OmcBizException(ErrorCodeEnum.GL99990002);
        }
        return goodsInfos;
    }

    @Override
    public List<ShopAndGoodsInfoDto> getShopAndGoodsBySpecId(Long specId, String longitude, String latitude, Long userId) {
        log.info("--- Enter getShopAndGoodsBySpecId(Long specId, String longitude, String latitude)，参数：{}, {}, {} ---", specId, longitude, latitude);
        List<ShopAndGoodsInfoDto> shopAndGoodsInfoDtos = new ArrayList<>();
//        List<GoodsDto> goodsDtos = new ArrayList<>();
//        if ("".equals(longitude) || "".equals(latitude)) {
//            //按价格排序
//            goodsDtos = shopGoodsMapper.getGoodsBySpecId(specId);
//        } else {
//            //综合排序
//            goodsDtos = this.getGoodsBySpecIdAndDis(specId, longitude, latitude);
//        }
//        if (goodsDtos.size() == 0) {
//            log.info("--- Leave getShopAndGoodsBySpecId(specId, longitude, latitude)：未找到对应商品，参数：{}, {}, {} ---", specId, longitude, latitude);
//            return null;
//        }
//
//        ProdSpecInfoDto prodSpecInfoDto = pmcFeignApi.getSpecInfoDtoBySpecId(specId);
//        if (prodSpecInfoDto == null) {
//            log.error("--- pmcFeignApi.getSpecInfoDtoBySpecId(specId)内部异常，参数：{} ---",specId);
//            throw new PmcBizException(ErrorCodeEnum.GL99990002);
//        }
////        List<GoodsInfo> goodsInfos = this.getCount(goodsDtos);
//        for (GoodsDto goodsDto : goodsDtos) {
////            for (GoodsInfo goodsInfo : goodsInfos) {
////                if (goodsInfo.getShopGoodsId().equals(goodsDto.getShopGoodsId())) {
////                    goodsDto.setCount(goodsInfo.getCount());
////                }
////            }
//            ShopAndGoodsInfoDto shopAndGoodsInfoDto = new ShopAndGoodsInfoDto();
//            List<GoodsInfoDto> goodsInfoDtos = new ArrayList<>();
//            GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
//            goodsInfoDto.setGoodsDto(goodsDto);
//            goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
//            goodsInfoDtos.add(goodsInfoDto);
//            ShopDto shopDto = shopService.getShopDtoByShopId(goodsDto.getShopId());
//            shopDto.setDistance(goodsDto.getDistance());
//            shopAndGoodsInfoDto.setShopDto(shopDto);
//            shopAndGoodsInfoDto.setGoodsInfoDtos(goodsInfoDtos);
//            shopAndGoodsInfoDtos.add(shopAndGoodsInfoDto);
//        }
//
//        //多条件排序:先sort，再价格(sql语句排序：先价格，再距离)
//        Comparator<ShopAndGoodsInfoDto> comparator = (s1, s2) -> {
//            if (s1.getGoodsInfoDtos().get(0).getGoodsDto().getSort().equals(s2.getGoodsInfoDtos().get(0).getGoodsDto().getSort())) {
//                return Integer.compare(s1.getGoodsInfoDtos().get(0).getGoodsDto().getSalePrice(), s2.getGoodsInfoDtos().get(0).getGoodsDto().getSalePrice());
//            }
//            return Integer.compare(s1.getGoodsInfoDtos().get(0).getGoodsDto().getSort(), s2.getGoodsInfoDtos().get(0).getGoodsDto().getSort());
//        };
////        shopAndGoodsInfoDtos.sort(comparator);
////        shopAndGoodsInfoDtos.sort(Comparator.comparingInt(ShopCartInfoDto -> ShopCartInfoDto.getGoodsDto().getSalePrice()));

        // todo V1.1版不再根据价格及综合排序，而是根据是否为推荐店铺及最近几个店铺进行排序
        ProdSpecInfoDto prodSpecInfoDto = pmcFeignApi.getSpecInfoDtoBySpecId(specId);

        if (prodSpecInfoDto == null) {
            return shopAndGoodsInfoDtos;
        }

        List<ShopDto> shopDtos = null;
        if (prodSpecInfoDto.getIsRetail()) {
            shopDtos = shopService.findNearShopsAndReferenceShop(longitude, latitude, this.deliverDistance, userId);
        } else {
            shopDtos = shopService.findNearSelfShops(longitude, latitude, this.deliverDistance);
        }

        // 获取商品的库存量
        if (shopDtos.size() > 0) {
            List<Long> specIds = new ArrayList<>();
            specIds.add(prodSpecInfoDto.getSpecId());
            Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityStockCount(shopDtos.get(0).getRegionCityId(), specIds);

            if (stockCount != null && stockCount.getCode() == 200) {
                Map<Long, Integer> stockCountMap = stockCount.getResult();

                List<GoodsDto> goodsDtos = new ArrayList<GoodsDto>();

                for (ShopDto shopDto : shopDtos) {
                    if ((!prodSpecInfoDto.getIsRetail() && shopDto.getShopType() == 4) || prodSpecInfoDto.getIsRetail()) {
                        ShopAndGoodsInfoDto shopAndGoodsInfoDto = new ShopAndGoodsInfoDto();
                        shopAndGoodsInfoDto.setShopDto(shopDto); // 设置店铺
                        List<GoodsInfoDto> goodsInfoDtoList = new ArrayList<>();

                        GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
                        GoodsDto goodsDtoTemp = new GoodsDto();
                        goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
                        goodsDtoTemp.setShopId(shopDto.getShopId());
                        goodsDtoTemp.setProductId(prodSpecInfoDto.getSpecId());
                        goodsDtoTemp.setStockCount(stockCountMap.get(prodSpecInfoDto.getSpecId()));
                        goodsDtoTemp.setSalePrice(prodSpecInfoDto.getSalePrice());
                        goodsInfoDto.setGoodsDto(goodsDtoTemp);
                        goodsDtos.add(goodsDtoTemp);
                        goodsInfoDtoList.add(goodsInfoDto);

                        shopAndGoodsInfoDto.setGoodsInfoDtos(goodsInfoDtoList);

                        shopAndGoodsInfoDtos.add(shopAndGoodsInfoDto);
                    }
                }

                // 设置月销量
                List<GoodsInfo> goodsInfoList = this.getCount(goodsDtos);
                for (GoodsDto goodsDto : goodsDtos) {
                    for (GoodsInfo goodsInfo : goodsInfoList) {
                        if (goodsDto.getShopId() == goodsDto.getShopId() && goodsInfo.getProductId() == goodsDto.getProductId()) {
                            goodsDto.setCount(goodsInfo.getCount());
                            break;
                        }
                    }
                }
            } else {
                return shopAndGoodsInfoDtos;
            }
        } else {
            return shopAndGoodsInfoDtos;
        }
        log.info("--- Leave getShopAndGoodsBySpecId(Long specId, String longitude, String latitude)，返回值大小：{} ---", shopAndGoodsInfoDtos.size());
        return shopAndGoodsInfoDtos;
    }

    @Override
    public List<ShopAndGoodsInfoDto> getShopAndGoodsBySearch(String search, String longitude, String latitude, Long userId) {
        log.info("--- Enter getShopAndGoodsBySearch(search, longitude, latitude)，参数：{}, {}, {} ---", search, longitude, latitude);
        List<ShopAndGoodsInfoDto> shopAndGoodsInfoDtos = new ArrayList<>();
        ProdSpecInfoDto prodSpecInfoDto = new ProdSpecInfoDto();
        prodSpecInfoDto.setSpecName(search);
        Wrapper<List<ProdSpecInfoDto>> prodSpecInfoDtoWrapper = pmcFeignApi.getSpecInfoDtosByCondition(prodSpecInfoDto);
        if (prodSpecInfoDtoWrapper.error()) {
            log.error("--- pmcFeignApi.getSpecInfoDtosByCondition(prodSpecInfoDto)内部异常，参数：{} ---", prodSpecInfoDto);
            throw new PmcBizException(ErrorCodeEnum.GL99990002);
        }
        List<ProdSpecInfoDto> prodSpecInfoDtoList = prodSpecInfoDtoWrapper.getResult().stream().filter(prodSpec -> prodSpec.getIsEnable() == 1 ).collect(Collectors.toList());
        if (prodSpecInfoDtoList.size() == 0) {
            log.info("--- Leave getShopAndGoodsBySearch(search, longitude, latitude)，调用pmcFeignApi.getSpecInfoDtosByCondition(prodSpecInfoDto)，未找到对应商品，参数：{}---", prodSpecInfoDto);
            return null;
        }
        List<Long> specIds = prodSpecInfoDtoList.stream().map(ProdSpecInfoDto::getSpecId).collect(Collectors.toList());

        // todo V1.1版不再根据价格及综合排序，而是根据是否为推荐店铺及最近几个店铺进行排序
//        List<ShopDto> shopDtos = new ArrayList<>();
//        if (longitude == null || latitude == null) {
//            //按价格排序
//            shopDtos = shopService.findShopsBySpecIds(specIds);
//        } else {
//            //综合排序
//            shopDtos = shopService.findShopsBySpecIdsAndDis(specIds, longitude, latitude);
//        }
//        List<Long> shopIds = shopDtos.stream().map(ShopDto::getShopId).collect(Collectors.toList());
//        List<GoodsDto> goodsDtos = shopGoodsMapper.getGoodsInfoByShopAndSpec(shopIds, specIds);
//        if (goodsDtos.size() == 0) {
//            log.info("--- Leave getShopAndGoodsBySearch(search, longitude, latitude)，调用shopGoodsMapper.getGoodsInfoByShopAndSpec(shopIds, specIds)，未找到对应商家售卖，参数：{}, {}---", shopIds, specIds);
//            return null;
//        }
//        List<Long> beingShopIds = goodsDtos.stream().map(GoodsDto::getShopId).distinct().collect(Collectors.toList());
//        List<GoodsInfo> goodsInfos = this.getCount(goodsDtos);
//        for (ShopDto shopDto : shopDtos) {
//            if (beingShopIds.contains(shopDto.getShopId())) {
//                ShopAndGoodsInfoDto shopAndGoodsInfoDto = new ShopAndGoodsInfoDto();
//                shopAndGoodsInfoDto.setShopDto(shopDto);
//                List<GoodsInfoDto> goodsInfoDtoList = new ArrayList<>();
//                for (GoodsDto goods : goodsDtos) {
//                    if (goods.getShopId().equals(shopDto.getShopId())) {
//                        for (GoodsInfo goodsInfo : goodsInfos) {
//                            if (goodsInfo.getShopId().equals(goods.getShopId())&&goodsInfo.getProductId().equals(goods.getProductId()))
//                                goods.setCount(goodsInfo.getCount());
//                        }
//                        GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
//                        goodsInfoDto.setGoodsDto(goods);
//                        for (ProdSpecInfoDto prodSpecInfo : prodSpecInfoDtoList) {
//                            if (prodSpecInfo.getSpecId().equals(goods.getProductId())) {
//                                goodsInfoDto.setProdSpecInfoDto(prodSpecInfo);
//                                goodsInfoDtoList.add(goodsInfoDto);
//                                shopAndGoodsInfoDto.setGoodsInfoDtos(goodsInfoDtoList);
//                            }
//                        }
//                    }
//                }
//                shopAndGoodsInfoDtos.add(shopAndGoodsInfoDto);
//            }
//        }

        // for test
//        List<ProdSpecInfoDto> prodSpecInfoDtoList = new ArrayList<>();
//        ProdSpecInfoDto prodSpecInfoDtoTemp = new ProdSpecInfoDto();
//        prodSpecInfoDtoTemp.setCategoryId(172290736401416192L);
//        prodSpecInfoDtoTemp.setSpecId(174160828496084992L);
//        prodSpecInfoDtoTemp.setSpecName("冰露水550ML");
//        prodSpecInfoDtoTemp.setUnitType((byte)0);
//        prodSpecInfoDtoTemp.setIsReturn(false);
//        prodSpecInfoDtoTemp.setReturnPeriod((byte)7);
//        prodSpecInfoDtoTemp.setCategoryName("饮用水");
//        prodSpecInfoDtoTemp.setParentId(172290561624768512L);
//        prodSpecInfoDtoTemp.setIsEnable((byte)1);
//        prodSpecInfoDtoTemp.setSalePrice(300);
//        prodSpecInfoDtoTemp.setIsFactory(false);
//        prodSpecInfoDtoTemp.setIsRetail(true);
//        prodSpecInfoDtoList.add(prodSpecInfoDtoTemp);

        // 对于店铺自营商品（不分销的商品）只获取附近的自营店铺，对于其他商品则获取推荐店铺+附近店铺
        // 先判断商品中是否只有不分销的商品，如果是则只查找附近的自营店铺，否则按正常流程查找店铺
        List<ShopDto> shopDtos = null;
        Boolean hasRetailSpec = false;
        for (ProdSpecInfoDto prodSpecInfo : prodSpecInfoDtoList) {
            if (prodSpecInfo.getIsRetail()) {
                hasRetailSpec = true;
                break;
            }
        }

        if (hasRetailSpec) {
            shopDtos = shopService.findNearShopsAndReferenceShop(longitude, latitude, this.deliverDistance, userId);
        } else {
            shopDtos = shopService.findNearSelfShops(longitude, latitude, this.deliverDistance);
        }

        // 获取商品的库存量
        if (shopDtos.size() > 0) {
            Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityStockCount(shopDtos.get(0).getRegionCityId(), specIds);
            // for test
//            Map<Long, Integer> map = new HashMap<>();
//            map.put(174160828496084992L, 30);
//            Wrapper<Map<Long, Integer>> stockCount = WrapMapper.ok(map);
            if (stockCount != null && stockCount.getCode() == 200) {
                Map<Long, Integer> stockCountMap = stockCount.getResult();

                List<GoodsDto> goodsDtos = new ArrayList<GoodsDto>();

                for (ShopDto shopDto : shopDtos) {
                    ShopAndGoodsInfoDto shopAndGoodsInfoDto = new ShopAndGoodsInfoDto();
                    shopAndGoodsInfoDto.setShopDto(shopDto); // 设置店铺
                    List<GoodsInfoDto> goodsInfoDtoList = new ArrayList<>();

                    for (ProdSpecInfoDto prodSpecInfo : prodSpecInfoDtoList) {
                        if ((!prodSpecInfoDto.getIsRetail() && shopDto.getShopType() == 4) || prodSpecInfoDto.getIsRetail()) {
                            GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
                            GoodsDto goodsDtoTemp = new GoodsDto();
                            goodsInfoDto.setProdSpecInfoDto(prodSpecInfo);
                            goodsDtoTemp.setShopId(shopDto.getShopId());
                            goodsDtoTemp.setProductId(prodSpecInfo.getSpecId());
                            goodsDtoTemp.setStockCount(stockCountMap.get(prodSpecInfo.getSpecId()));
                            goodsDtoTemp.setSalePrice(prodSpecInfo.getSalePrice());
                            goodsInfoDto.setGoodsDto(goodsDtoTemp);
                            goodsDtos.add(goodsDtoTemp);
                            goodsInfoDtoList.add(goodsInfoDto);
                        }
                    }
                    shopAndGoodsInfoDto.setGoodsInfoDtos(goodsInfoDtoList);

                    shopAndGoodsInfoDtos.add(shopAndGoodsInfoDto);
                }

                // 设置月销量
                List<GoodsInfo> goodsInfoList = this.getCount(goodsDtos);
                for (GoodsDto goodsDto : goodsDtos) {
//                    goodsDto.setCount(23);  // for test
                    for (GoodsInfo goodsInfo : goodsInfoList) {
                        if (goodsDto.getShopId() == goodsDto.getShopId() && goodsInfo.getProductId() == goodsDto.getProductId()) {
                            goodsDto.setCount(goodsInfo.getCount());
                            break;
                        }
                    }
                }
            } else {
                return shopAndGoodsInfoDtos;
            }
        } else {
            return shopAndGoodsInfoDtos;
        }

        //TODO:排序未做，等数据量多了，再看怎么排序
        log.info("--- Leave getShopAndGoodsBySearch(search, longitude, latitude),返回值大小：{} ---", shopAndGoodsInfoDtos.size());
        return shopAndGoodsInfoDtos;
    }

    @Override
    public List<StockGoodsDto> getStockGoodsByCategoryIdAndShopId(Long shopId, Long categoryId, Integer isAlive) {
        log.info("--- Enter getStockGoodsByCategoryIdAndShopId(Long shopId, Long categoryId, Integer isAlive)，参数：{}, {},{} ---", shopId, categoryId, isAlive);
        List<StockGoodsDto> stockGoodsDtos = new ArrayList<>();
        List<ProdSpecInfoDto> prodSpecInfoDtos = pmcFeignApi.getSpecInfoDtosByCategoryId(categoryId);
        List<Long> specIds = prodSpecInfoDtos.stream().map(ProdSpecInfoDto::getSpecId).collect(Collectors.toList());
        List<ShopGoods> shopGoods = shopGoodsMapper.getStockGoodsByShopIdAndSpecIds(shopId, specIds, isAlive);
        if (shopGoods.size() == 0) {
            log.info("--- Leave getStockGoodsByCategoryIdAndShopId(Long shopId, Long categoryId, Integer isAlive)，该条件下没有商品，返回值：{} ---", stockGoodsDtos);
            return stockGoodsDtos;
        }
        Map<String, List<Long>> map = new HashMap<>();
        List<Long> list = new ArrayList<>();
        list.add(shopId);
        map.put("shopId", list);
        map.put("specIds", shopGoods.stream().map(shopGoods1 -> shopGoods1.getProductId()).collect(Collectors.toList()));
        List<Map> numByShopAndSpecs = omcOrderFeignApi.gethistorynum(map);
        if (numByShopAndSpecs == null || numByShopAndSpecs.size() == 0) {
            log.error("--- omcOrderFeignApi.gethistorynum(map)内部异常，参数：{} ---", map);
            throw new OmcBizException(ErrorCodeEnum.GL99990002);
        }
        for (ShopGoods goods : shopGoods) {
            for (Map numMap : numByShopAndSpecs) {
                if (goods.getProductId().equals(Long.valueOf(numMap.get("specId").toString()))) {
                    goods.setNum(Integer.valueOf(numMap.get("nums").toString()));
                }
            }
            StockGoodsDto stockGoodsDto = new StockGoodsDto();
            stockGoodsDto.setShopGoods(goods);
            for (ProdSpecInfoDto prodSpecInfoDto : prodSpecInfoDtos) {
                if (goods.getProductId().equals(prodSpecInfoDto.getSpecId())) {
                    stockGoodsDto.setProdSpecInfoDto(prodSpecInfoDto);
                    stockGoodsDtos.add(stockGoodsDto);
                }
            }
        }

//        shopGoods.parallelStream().forEach(goods ->{
//                    Optional<Map> m = numByShopAndSpecs.stream()
//                            .filter(num -> Long.valueOf(num.get("specId").toString()).equals(goods.getProductId())).findFirst();
//                    if (m.isPresent())
//                        goods.setNum(Integer.valueOf(m.get().get("nums").toString()));
//                    StockGoodsDto stockGoodsDto = new StockGoodsDto();
//                    stockGoodsDto.setShopGoods(goods);
//                    Optional<ProdSpecInfoDto> prodSpecInfoDto = prodSpecInfoDtos.stream()
//                            .filter(prodSpecInfo -> prodSpecInfo.getSpecId().equals(goods.getProductId())).findFirst();
//                    if (prodSpecInfoDto.isPresent()) {
//                        stockGoodsDto.setProdSpecInfoDto(prodSpecInfoDto.get());
//                        stockGoodsDtos.add(stockGoodsDto);
//                    }
//                });
        log.info("--- Leave getStockGoodsByCategoryIdAndShopId(Long shopId, Long categoryId, Integer isAlive)，返回值大小：{} ---", stockGoodsDtos.size());
        return stockGoodsDtos;
    }

    @Override
    public List<GoodsInfoDto> getShopGoodsByShopIdAndCategoryId(Long shopId, Long categoryId) {
        List<GoodsInfoDto> goodsInfoDtos = new ArrayList<>();

//        List<GoodsDto> goodsDtos = shopGoodsMapper.getGoodsByShopId(shopId);
//        if (goodsDtos.size() == 0) {
//            return goodsInfoDtos;
//        }
//        List<ProdSpecInfoDto> prodSpecInfoDtos = pmcFeignApi.getSpecInfoDtosByCategoryId(categoryId).stream().filter(prodSpecInfoDto -> prodSpecInfoDto.getIsEnable() == 1).collect(Collectors.toList());
//        List<GoodsInfo> goodsInfos = this.getCount(goodsDtos);
//        for (GoodsDto goodsDto : goodsDtos) {
//            for (ProdSpecInfoDto prodSpecInfoDto : prodSpecInfoDtos) {
//                if (goodsDto.getProductId().equals(prodSpecInfoDto.getSpecId())) {
//                    GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
//                    goodsInfoDto.setGoodsDto(goodsDto);
//                    goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
//                    goodsInfoDtos.add(goodsInfoDto);
//                }
//            }
//            for (GoodsInfo goodsInfo : goodsInfos) {
//                if (goodsDto.getShopGoodsId().equals(goodsInfo.getShopGoodsId())) {
//                    goodsDto.setCount(goodsInfo.getCount());
//                }
//            }
//        }

        // todo V1.1版商品与店铺之间的逻辑有变化
        List<ProdCategoryDto> prodCategoryDtos = new ArrayList<>();
        ShopDto shopDto = shopService.getShopDtoByShopId(shopId);
        // 获取可售卖的商品及数量
        Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityAllStockCount(shopDto.getRegionCityId());

        if (stockCount != null && stockCount.getCode() == 200) {
            Map<Long, Integer> stockCountMap = stockCount.getResult();

            List<GoodsDto> goodsDtos = new ArrayList<GoodsDto>();

            List<ProdSpecInfoDto> prodSpecInfoDtos = pmcFeignApi.getSpecInfoDtosByCategoryId(categoryId).stream().filter(prodSpecInfoDto -> prodSpecInfoDto.getIsEnable() == 1).collect(Collectors.toList());

            Iterator it = stockCountMap.keySet().iterator();

            for (ProdSpecInfoDto prodSpecInfoDto : prodSpecInfoDtos) {
                while (it.hasNext()) {
                    String key = it.next().toString();
                    if (Long.valueOf(key).equals(prodSpecInfoDto.getSpecId())) {
                        if ((!prodSpecInfoDto.getIsRetail() && shopDto.getShopType() == 4) || prodSpecInfoDto.getIsRetail()) {
                            GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
                            GoodsDto goodsDto = new GoodsDto();

                            goodsDto.setSalePrice(prodSpecInfoDto.getSalePrice());
                            goodsDto.setShopId(shopId);
                            goodsDto.setProductId(prodSpecInfoDto.getSpecId());
                            goodsDto.setStockCount(stockCountMap.get(prodSpecInfoDto.getSpecId()));

                            goodsInfoDto.setGoodsDto(goodsDto);
                            goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
                            goodsInfoDtos.add(goodsInfoDto);

                            goodsDtos.add(goodsDto);

                            break;
                        }
                    }
                }
            }

            // 设置月销量
            List<GoodsInfo> goodsInfoList = this.getCount(goodsDtos);
            for (GoodsDto goodsDto : goodsDtos) {
                for (GoodsInfo goodsInfo : goodsInfoList) {
                    if (goodsDto.getShopId() == goodsDto.getShopId() && goodsInfo.getProductId() == goodsDto.getProductId()) {
                        goodsDto.setCount(goodsInfo.getCount());
                        break;
                    }
                }
            }
        }

        return goodsInfoDtos;
    }

    @Override
    public PageInfo<StockGoodsDto> getStockGoodsByCondition(ShopGoods shopGoods, Integer page , Integer size) {
        List<StockGoodsDto> stockGoodsDtos = new ArrayList<>();
        ProdSpecInfoDto prodSpecInfoDto = new ProdSpecInfoDto();
        if (shopGoods.getProductId() != null)
            prodSpecInfoDto.setSpecId(shopGoods.getProductId());
        if (shopGoods.getCategoryId() != null)
            prodSpecInfoDto.setCategoryId(shopGoods.getCategoryId());
        Wrapper<List<ProdSpecInfoDto>> listWrapper = pmcFeignApi.getSpecInfoDtosByCondition(prodSpecInfoDto);
        if (listWrapper.error()) {
            log.error("--- pmcFeignApi.getSpecInfoDtosByCondition(prodSpecInfoDto)内部异常，参数：{} ---", prodSpecInfoDto);
            throw new PmcBizException(ErrorCodeEnum.GL99990002);
        }
        List<ProdSpecInfoDto> prodSpecInfoDtos = listWrapper.getResult();
        if (prodSpecInfoDtos == null || prodSpecInfoDtos.size() == 0) {
            PageInfo pageInfo = new PageInfo(stockGoodsDtos);
            return pageInfo;
        }
        List<Long> specIds = prodSpecInfoDtos.stream().map(prodSpecInfoDto1 -> prodSpecInfoDto1.getSpecId()).collect(Collectors.toList());
        PageHelper.startPage(page, size);
        List<ShopGoods> shopGoodsList = shopGoodsMapper.getStockGoodsByCondition(shopGoods, specIds);
        if (shopGoodsList == null || shopGoodsList.size() == 0) {
            PageInfo pageInfo = new PageInfo(stockGoodsDtos);
            return pageInfo;
        }
        for (ShopGoods goods : shopGoodsList) {
            StockGoodsDto stockGoodsDto = new StockGoodsDto();
            stockGoodsDto.setShopGoods(goods);
            for (ProdSpecInfoDto specInfoDto : prodSpecInfoDtos) {
                if (goods.getProductId().equals(specInfoDto.getSpecId())) {
                    stockGoodsDto.setProdSpecInfoDto(specInfoDto);
                    stockGoodsDtos.add(stockGoodsDto);
                }
            }
        }
        PageInfo pageInfo = new PageInfo(shopGoodsList);
        pageInfo.setList(stockGoodsDtos);
        return pageInfo;
    }

    @Override
    public ShopGoodsInfoDto getShopGoodsInfoByShopId(Long shopId) {
        //TODO:少一个月销量
        ShopGoodsInfoDto shopGoodsInfoDto = new ShopGoodsInfoDto();
        ShopDto shopDto = shopService.getShopDtoByShopId(shopId);
        shopGoodsInfoDto.setShopDto(shopDto);

        // todo V1.1版商品与店铺之间的逻辑有变化
        List<GoodsInfoDto> goodsInfoDtos = new ArrayList<>();
        List<ProdCategoryDto> prodCategoryDtos = new ArrayList<>();
        // 获取可售卖的商品及数量
        Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityAllStockCount(shopDto.getRegionCityId());

        if (stockCount != null && stockCount.getCode() == 200) {
            Map<Long, Integer> stockCountMap = stockCount.getResult();

            List<GoodsDto> goodsDtos = new ArrayList<GoodsDto>();

            Iterator it = stockCountMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next().toString();
                ProdSpecInfoDto prodSpecInfoDto = pmcFeignApi.getSpecInfoDtoBySpecId(Long.valueOf(key));

                if (prodSpecInfoDto != null) {
                    if ((!prodSpecInfoDto.getIsRetail() && shopDto.getShopType() == 4) || prodSpecInfoDto.getIsRetail()) {
                        GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
                        GoodsDto goodsDto = new GoodsDto();

                        goodsDto.setShopId(shopDto.getShopId());
                        goodsDto.setProductId(prodSpecInfoDto.getSpecId());
                        goodsDto.setStockCount(stockCountMap.get(prodSpecInfoDto.getSpecId()));
                        goodsDto.setSalePrice(prodSpecInfoDto.getSalePrice());

                        goodsInfoDto.setGoodsDto(goodsDto);
                        goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
                        goodsInfoDtos.add(goodsInfoDto);

                        goodsDtos.add(goodsDto);
                    }
                }
            }

            List<Long> specIds = new ArrayList<Long>();
            // 设置月销量
            List<GoodsInfo> goodsInfoList = this.getCount(goodsDtos);
            for (GoodsDto goodsDto : goodsDtos) {
                specIds.add(goodsDto.getProductId());
                for (GoodsInfo goodsInfo : goodsInfoList) {
                    if (goodsDto.getShopId() == goodsDto.getShopId() && goodsInfo.getProductId() == goodsDto.getProductId()) {
                        goodsDto.setCount(goodsInfo.getCount());
                        break;
                    }
                }
            }

            prodCategoryDtos = pmcFeignApi.getCategorysBySpecIds(specIds);

            shopGoodsInfoDto.setProdCategoryDtos(prodCategoryDtos);
        }

//        List<GoodsInfoDto> goodsInfoDtos = new ArrayList<>();
//        List<GoodsDto> goodsDtos = shopGoodsMapper.getGoodsByShopId(shopId);
//        if (goodsDtos.size() == 0) {
//            return shopGoodsInfoDto;
//        }
//        List<ProdCategoryDto> prodCategoryDtos = pmcFeignApi.getCategorysBySpecIds(goodsDtos.stream().map(shopGoods1 -> shopGoods1.getProductId()).collect(Collectors.toList()));
////        List<GoodsInfo> goodsInfos = this.getCount(goodsDtos);
//        for (GoodsDto goodsDto : goodsDtos) {
//            ProdSpecInfoDto prodSpecInfoDto = pmcFeignApi.getSpecInfoDtoBySpecId(goodsDto.getProductId());
//            if (prodSpecInfoDto != null) {
//                GoodsInfoDto goodsInfoDto = new GoodsInfoDto();
//                goodsInfoDto.setGoodsDto(goodsDto);
//                goodsInfoDto.setProdSpecInfoDto(prodSpecInfoDto);
//                goodsInfoDtos.add(goodsInfoDto);
//            }
//
////            for (GoodsInfo goodsInfo : goodsInfos) {
////                if (goodsDto.getShopGoodsId().equals(goodsInfo.getShopGoodsId())) {
////                    goodsDto.setCount(goodsInfo.getCount());
////                }
////            }
//        }
        shopGoodsInfoDto.setGoodsInfoDtos(goodsInfoDtos);
        shopGoodsInfoDto.setProdCategoryDtos(prodCategoryDtos);
        return shopGoodsInfoDto;
    }

    @Override
    public List<ProdCategoryDto> getShopCategoryIsAliveByShopId(Long shopId) {
        List<ProdCategoryDto> prodCategoryDtos = new ArrayList<>();

//        List<ShopGoods> shopGoods = shopGoodsMapper.getIsAliveStockGoodsByShopId(shopId);
//        if (shopGoods.size() == 0) {
//            return prodCategoryDtos;
//        }
//        prodCategoryDtos = pmcFeignApi.getCategorysBySpecIds(shopGoods.stream().map(shopGoods1 -> shopGoods1.getProductId()).collect(Collectors.toList()));

        // todo V1.1版商品与店铺之间的逻辑有变化
        ShopDto shopDto = shopService.getShopDtoByShopId(shopId);
        List<GoodsInfoDto> goodsInfoDtos = new ArrayList<>();
        List<Long> specIds = new ArrayList<Long>();
        // 获取可售卖的商品及数量
        Wrapper<Map<Long, Integer>> stockCount = wmcStorageFeignApi.getCityAllStockCount(shopDto.getRegionCityId());

        if (stockCount != null && stockCount.getCode() == 200) {
            Map<Long, Integer> stockCountMap = stockCount.getResult();

            Iterator it = stockCountMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next().toString();
                specIds.add(Long.valueOf(key));
            }

            prodCategoryDtos = pmcFeignApi.getCategorysBySpecIds(specIds);
        }

        return prodCategoryDtos;
    }

    @Override
    public List<ProdCategoryDto> getShopCategoryAllByShopId(Long shopId) {
        List<ProdCategoryDto> prodCategoryDtos = new ArrayList<>();
        ShopGoods goods = new ShopGoods();
        goods.setShopId(shopId);
        List<ShopGoods> shopGoods = shopGoodsMapper.select(goods);
        if (shopGoods.size() == 0) {
            return prodCategoryDtos;
        }
        prodCategoryDtos = pmcFeignApi.getCategorysBySpecIds(shopGoods.stream().map(shopGoods1 -> shopGoods1.getProductId()).collect(Collectors.toList()));
        return prodCategoryDtos;
    }

    @Override
    public Integer updateStockCount(Long shopId, Long specId, Integer goodsNum) {
        return shopGoodsMapper.updateStockCount(shopId, specId, goodsNum);
    }

    @Override
    public Byte getGoodsStatus(Long shopId, Long specId) {
        return shopGoodsMapper.getGoodsStatus(shopId, specId);
    }

    @Override
    public List<GoodsAndSpecInfoDto> getGoodsStatusList(List<GoodsAndSpecInfoDto> goodsAndSpecInfoDtos) {
        for (GoodsAndSpecInfoDto goodsAndSpecInfoDto : goodsAndSpecInfoDtos) {
            Byte status = shopGoodsMapper.getGoodsStatus(goodsAndSpecInfoDto.getShopId(), goodsAndSpecInfoDto.getSpecId());
            goodsAndSpecInfoDto.setGoodsStatus(status);
        }
        return goodsAndSpecInfoDtos;
    }

    @Override
    public Integer getLowPriceBySpecId(Long specId) {
        return shopGoodsMapper.getLowPriceBySpecId(specId);
    }

    @Override
    public List<GoodsAndSpecInfoDto> getShopGoodsSalePrice(ShopGoodsSalePriceDto shopGoodsSalePriceDto) {
        BigDecimal longitudeDecimal = null;
        BigDecimal latitudeDecimal = null;
        if (shopGoodsSalePriceDto.getLongitude() != null && shopGoodsSalePriceDto.getLatitude() != null) {
            longitudeDecimal = new BigDecimal(shopGoodsSalePriceDto.getLongitude());
            latitudeDecimal = new BigDecimal(shopGoodsSalePriceDto.getLatitude());
        }
        return shopGoodsMapper.getShopGoodsSalePrice(shopGoodsSalePriceDto.getSpecIds(), longitudeDecimal, latitudeDecimal, this.deliverDistance);
    }

    /*private List<GoodsDto> getGoodsBySpecIdAndDis(Long specId, String longitude, String latitude, Integer deliverDistance) {
        BigDecimal longitudeDecimal = new BigDecimal(longitude);
        BigDecimal latitudeDecimal = new BigDecimal(latitude);
        List<GoodsDto> goodsDtos = shopGoodsMapper.getGoodsBySpecIdAndDis(specId, longitudeDecimal, latitudeDecimal, deliverDistance);
        return goodsDtos;
    }*/

    private List<GoodsDto> getGoodsBySpecIdAndDis(Long specId, String longitude, String latitude) {
        BigDecimal longitudeDecimal = new BigDecimal(longitude);
        BigDecimal latitudeDecimal = new BigDecimal(latitude);
        List<GoodsDto> goodsDtos = shopGoodsMapper.getGoodsBySpecIdAndDis(specId, longitudeDecimal, latitudeDecimal);
        return goodsDtos;
    }

    @Override
    public int save(ShopGoods record) {
        record.setShopGoodsId(generateId());
        return super.save(record);
    }
}
